"""Pydantic 模型工具函数."""

from __future__ import annotations

import sys
from typing import Any, Dict, List

from pydantic import BaseModel


def rebuild_pydantic_models(*models: type) -> None:
    """重建 Pydantic 模型，确保类型注解正确解析。
    
    当通过 runpy.run_module 运行时，需要确保所有类型在命名空间中。
    这解决了通过 python -m 运行时命名空间不完整的问题。
    
    使用场景：
        - 在工具的 main() 测试方法中调用
        - 确保通过 `python -m src.tools.xxx` 运行时模型能正确解析类型注解
    
    Args:
        *models: 要重建的模型类（BaseModel 或 BaseTool 子类）
    
    Example:
        >>> from src.utils.pydantic_utils import rebuild_pydantic_models
        >>> from src.workflows.model_prediction import ModelPredictionInput, ModelPredictionTool
        >>> 
        >>> def main() -> None:
        ...     rebuild_pydantic_models(ModelPredictionInput, ModelPredictionTool)
        ...     # ... 其他测试代码
    """
    # 获取调用者的模块（即调用此函数的模块）
    # sys._getframe(1) 获取调用栈中上一层的帧对象
    frame = sys._getframe(1)
    # 从帧对象的全局命名空间中获取模块名，然后从 sys.modules 中获取模块对象
    current_module = sys.modules[frame.f_globals["__name__"]]
    
    # 确保 BaseModel 和相关类型在模块的命名空间中（用于 model_rebuild）
    # 这解决了通过 runpy.run_module 运行时命名空间不完整的问题
    # 如果模块中没有这些类型，就添加它们，这样 Pydantic 的 model_rebuild 才能正确解析类型注解
    if not hasattr(current_module, "BaseModel"):
        current_module.BaseModel = BaseModel
    if not hasattr(current_module, "Dict"):
        current_module.Dict = Dict
    if not hasattr(current_module, "Any"):
        current_module.Any = Any
    if not hasattr(current_module, "List"):
        current_module.List = List
    
    # 将传入的模型类添加到模块命名空间
    # 这样在重建模型时，模型内部引用的其他模型类也能被正确解析
    for model in models:
        model_name = model.__name__
        if not hasattr(current_module, model_name):
            setattr(current_module, model_name, model)
    
    # 重建所有模型，确保所有类型注解都被正确解析
    # 注意：Pydantic v2 的 model_rebuild 可能需要正确的命名空间上下文
    # 如果重建失败，可能是模型已经正确初始化，这是正常的，所以捕获异常但不报错
    for model in models:
        try:
            model.model_rebuild()
        except Exception:
            # 如果重建失败，可能是模型已经正确初始化
            # 在某些情况下，模型可能已经正确初始化，这是正常的
            pass

